#include "ThingsBoard.h"
#include <ESP8266WiFi.h>
int Status = 12;  // Digital pin D6 ring
int port = A0;//连接火焰传感器
int sensor = 13;  // Digital pin D7  LED
#define SensorINPUT 14 // D1 shock 震动传感器
int timeOut = 0;
int flag = 0;
int value = 0;//测量的模拟数值
bool switch_state = false;
int loopNum = 0;
int flagNum = 0;
int stateFlag = 0;
unsigned char state = 0;
int shockStatus = 0;
//#define WIFI_AP             "yiceng"
//#define WIFI_PASSWORD       "**********"
#define WIFI_AP             "*****"
#define WIFI_PASSWORD       "*********"
// See https://thingsboard.io/docs/getting-started-guides/helloworld/
// to understand how to obtain an access token
#define TOKEN          "cen2smvJi5gZ4FJFYUnN"          //"yvHXKmV87ecYa6Bx8uHD"
#define THINGSBOARD_SERVER  "106.12.252.**"
#define PORT          1883          //"yvHXKmV87ecYa6Bx8uHD"
//#define THINGSBOARD_SERVER  "192.168.1.147"            //"117.34.95.33"

// Serial driver for ESP
// Initialize the Ethernet client object
WiFiClient espClient;
// Initialize ThingsBoard instance
ThingsBoard tb(espClient);
// the Wifi radio's status
int status = WL_IDLE_STATUS;

void setup() {
  // initialize serial for debugging
  Serial.begin(9600);
  // initialize serial for ESP module
  pinMode(Status, OUTPUT);  // declare LED as output
  pinMode(sensor, OUTPUT);   // LED status
  digitalWrite(sensor, HIGH);
  pinMode(SensorINPUT, INPUT);
  attachInterrupt(SensorINPUT, blink, CHANGE);// Trigger the blinkfunction when the falling edge is detected
  // initialize ESP module
  WiFi.begin(WIFI_AP, WIFI_PASSWORD);
  
  InitWiFi();
}

// Processes function for RPC call "example_set_temperature"
// RPC_Data is a JSON variant, that can be queried using operator[]
// See https://arduinojson.org/v5/api/jsonvariant/subscript/ for more details
RPC_Response processTemperatureChange(const RPC_Data &data)
{
  Serial.println("Received the set temperature RPC method");

  // Process data

  float example_temperature = data["temp"];

  Serial.print("Example temperature: ");
  Serial.println(example_temperature);

  // Just an response example
  return RPC_Response("example_response", 42);
}

// Processes function for RPC call "example_set_switch"
// RPC_Data is a JSON variant, that can be queried using operator[]
// See https://arduinojson.org/v5/api/jsonvariant/subscript/ for more details
RPC_Response processSwitchChange(const RPC_Data &data)
{
  Serial.println("Received the set switch method");

  // Process data
  
  switch_state = data["switch"];
  
  Serial.print("Example switch state: ");
  Serial.println(switch_state);
  if(switch_state){
    //digitalWrite (Status, HIGH);
    tb.sendTelemetryInt("buzzer", 1);
    
  }else{
    digitalWrite (Status, LOW);
    //digitalWrite(sensor,LOW);
    tb.sendTelemetryInt("buzzer", 0);
    //tb.sendTelemetryInt("fire", 0);
  }
  // Just an response example
  return RPC_Response("example_response", 22.02);
}

const size_t callbacks_size = 2;
RPC_Callback callbacks[callbacks_size] = {
  { "example_set_temperature",    processTemperatureChange },
  { "open",         processSwitchChange }
};

bool subscribed = false;

void loop() {
  delay(500);

  if (WiFi.status() != WL_CONNECTED) {
    // Still connecting
    reconnect();
  }
  Serial.println("333333333333");
  Serial.println(WiFi.localIP());
  if (!tb.connected()) {
    subscribed = false;

    // Connect to the ThingsBoard
    Serial.print("Connecting to: ");
    Serial.print(THINGSBOARD_SERVER);
    Serial.print(" with token ");
    Serial.println(TOKEN);
    if (!tb.connect(THINGSBOARD_SERVER, TOKEN, PORT)) {
      Serial.println("Failed to connect, retrying ...");
      return;
    }
  }
  value = analogRead(port);
  Serial.println(value);

  if(value < 100){
    flag = 1;
    timeOut=0;
    
    digitalWrite(sensor, HIGH);
    digitalWrite (Status, HIGH);
    if(flagNum<1){
      tb.sendTelemetryInt("fire", 1);
    }
    if(loopNum>20){
      tb.sendTelemetryInt("fire", 1);
      loopNum=0;
    }    
    flagNum++;
  }else{
    if(flag==1){
      flagNum = 0;
      Serial.println(timeOut);
      if(timeOut > 5){
        switch_state = 0;
        tb.sendTelemetryInt("fire", 0);
        Serial.println("------------------");
        digitalWrite(sensor, LOW);
        digitalWrite (Status, LOW);
        tb.sendTelemetryInt("fire", 0);
        flag=0;
        timeOut=0;
        flagNum=0;
        }else{
          digitalWrite(sensor, HIGH);
          digitalWrite (Status, HIGH);
          if(flagNum<1){
            tb.sendTelemetryInt("fire", 1); 
          }
          flagNum++; 
        }
              
        timeOut++;
    }else{
        //digitalWrite(sensor, LOW);
        digitalWrite (Status, LOW);
        flagNum=0;
        if(loopNum>20){
          tb.sendTelemetryInt("fire", 0);
          loopNum=0;
        }
    }
    
  }
  loopNum++;
  if (!subscribed) {
    Serial.println("Subscribing for RPC...");

    // Perform a subscription. All consequent data processing will happen in
    // processTemperatureChange() and processSwitchChange() functions,
    // as denoted by callbacks[] array.
    if (!tb.RPC_Subscribe(callbacks, callbacks_size)) {
      Serial.println("Failed to subscribe for RPC");
      return;
    }

    Serial.println("Subscribe done");
    subscribed = true;
  }

  Serial.println("Waiting for data...");

  if(switch_state){
      digitalWrite(sensor,HIGH);
      digitalWrite (Status, HIGH);
      delay(100);
      digitalWrite(sensor,LOW);
      digitalWrite (Status, LOW);
    }else{
      digitalWrite(sensor,HIGH);
    }

    if (state != 0)
    {
      state = 0;
      int lops = 1;
      shockStatus = 1;
      tb.sendTelemetryInt("shock", 1);
      while(lops>0){
        digitalWrite (sensor, HIGH);
        delay(10);  //小灯点亮时间
        digitalWrite (sensor, LOW);
        lops--;
      }
    }
    else{
      if(shockStatus==1){
        tb.sendTelemetryInt("shock", 0);
        shockStatus=0;
      }
      Serial.println(state);
      if(loopNum>19){
        tb.sendTelemetryInt("shock", 0);
      }
      digitalWrite (sensor, HIGH); 
    }        
  tb.loop();
}

void InitWiFi()
{
  Serial.println("Connecting to AP ...");
  // attempt to connect to WiFi network

  WiFi.begin(WIFI_AP, WIFI_PASSWORD);
  //stat_info = wifi_softap_get_station_info();
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected to AP");
}

void reconnect() {
  // Loop until we're reconnected
  status = WiFi.status();
  Serial.println(WiFi.localIP());
  if ( status != WL_CONNECTED) {
    WiFi.begin(WIFI_AP, WIFI_PASSWORD);
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }
    Serial.println("Connected to AP");
  }
}

ICACHE_RAM_ATTR void blink()//Interrupts function
{
  state++;
  Serial.println("receive");
  Serial.println(digitalRead(SensorINPUT));
}
